"""
本模块描述了关于活塞递归的若干算法，可以根据活塞数量得到指令组
一个指令组可以由 [[1,2,3,...],[1,2,3,...],...] 表示，
每个子数组的元素表示此tick内同时激活的活塞下标。
"""

from typing import *


def extension(N: int) -> List[List[int]]:
    steps = []
    for i in range(0, 2 * N, 2):
        steps.append([i])
    return steps


from itertools import count
def impulse(N: int, cnt: int = 1, itvl: int = -1) -> Generator[List[int],None,None]:
    cnt -= 1
    subStep = [0]

    ub = range(0, 2 * N + cnt * itvl, 1)
    prevsteps = []
    
    if itvl > 2*N:
        return impulse(N, 1, -1)*cnt        
        
    if cnt <= -1:
        ub = count(0)
    
    for i in ub:
        if itvl > 0:
            if i % itvl == 0 and cnt != 0:
                cnt -= 1
                subStep = [0]
            else:
                subStep = []
            
            subStep.extend(list((k + 1) for k in prevsteps if k < 2*N-1))
            prevsteps = subStep

            yield subStep
        else:
            yield [i]


def substractbk(N : int) -> List[List[int]]:
    
    stp = []

    for i in range(N+1):
        for j in range(i):
            stp.append(2*N-2*i + j)

    return [[i] for i in stp]

def substract(N: int) -> List[List[int]]:
    steps = []
    msk = [0 for i in range(2 * N)]

    for i in range(2 * N - 2, -1, -2):

        msk.insert(0, 0)
        msk = msk[0: N + N // 2 + i // 4]

        msk[i] = 1
        sub_stp = []
        for x in range(len(msk)):
            if msk[x] != 0:
                sub_stp.append(x)
        steps.append(sub_stp)

    for i in range(0, N - 1):

        msk.insert(0, 0)
        msk = msk[0:N + N // 2 - i // 2 - 1]

        sub_stp = []
        for x in range(len(msk)):
            if msk[x] != 0:
                sub_stp.append(x)
        steps.append(sub_stp)
    return steps
